//
// Created by 鱼涛 on 2017/12/25.
// Copyright (c) 2017 Facebook. All rights reserved.
//

import Foundation
import UIKit
import SnapKit
import SwiftHash

enum KeyboardType : Int{
    case noting
    case voice      //语音
    case text       //文字
    case emotion    //表情
    case more       //更多
}

class InputSectionView: UIView {
    weak var delegate: InputSectionViewDelegate?
    var msgSendInterval: Bool?  //是否弹出 5秒间隔的提示框
    var roleisAdminOrSelf: Bool?  // 当前用户是否是管理员 (在单聊和群聊情况下, 默认当前登录用户是管理员; 在聊天室, 需判断是admin 还是member)
    var enableAt:Bool = false  //是否允许At功能
    
    var inputSectionHeight = CGFloat(0)
    var nameArr:[String] = []
    var selectedRange: NSRange?
    var atModel = AtModel<Int>()
    
    let margin = CGFloat(5)
    private let btnWidthOrHeight = CGFloat(35)
    private let _5LinesHeight = CGFloat(119)
    private let _6LinesHeight = CGFloat(130)
    
    private var preMsgSendTime:TimeInterval?
    
    var keyboardType:PropertyObservable<KeyboardType>? {
        didSet {
        }
    }
    
    lazy var textView: UITextView = {
        let textV = UITextView()
        textV.layoutManager.allowsNonContiguousLayout = false
        //设置键盘输入样式为send
        textV.returnKeyType = .send
        textV.enablesReturnKeyAutomatically = true
        textV.delegate = self
        textV.backgroundColor = UIColor(named: "chat_input_textview_bg")
        textV.layer.cornerRadius = 5
        textV.layer.borderWidth = 0.5
        let textViewFont = UIFont.systemFont(ofSize: kInputViewFontSize)
        textV.font = textViewFont
        textV.isScrollEnabled = false
        textV.layer.borderWidth = 0
        textV.addObserver(self, forKeyPath: "attributedText", options: .new, context: nil)
        return textV
    }()
    
    lazy var reasonLabel:UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.text = "禁言"
        label.isHidden = true
        return label
    }()
    
    lazy var voiceButton: UIButton = {
        let voiceBtn = UIButton(type: .custom)
        voiceBtn.addTarget(self, action: #selector(voiceBtnClick(_:)), for: .touchUpInside)
        voiceBtn.setImage(#imageLiteral(resourceName:"ToolViewInputVoice"), for: .normal)
        voiceBtn.setImage(#imageLiteral(resourceName:"ToolViewInputVoiceHL"), for: .highlighted)
        return voiceBtn
    }()
    
    lazy var recordButton: UIButton = {
        let recordBtn = UIButton(type: .custom)
        recordBtn.backgroundColor = UIColor(named: "chat_input_textview_bg")
        recordBtn.setTitle(recordBtnTextTalk, for: .normal)
        recordBtn.setTitle(recordBtnTextStop, for: .highlighted)
        recordBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14.0)
        recordBtn.setTitleColor(UIColor.secondaryLabel, for: .normal)
        recordBtn.setTitleColor(UIColor.secondaryLabel, for: .highlighted)
        recordBtn.layer.cornerRadius = 4.0
        recordBtn.layer.masksToBounds = true
        recordBtn.layer.borderWidth = 0
        recordBtn.isHidden = true
        // 录音按钮的事件
        let longTap = UILongPressGestureRecognizer(target: self, action: #selector(voiceBtnLongTap(_:)))
        longTap.minimumPressDuration = 0.1 //长按触发时间
        recordBtn.addGestureRecognizer(longTap)
        return recordBtn
    }()
    
    //表情按钮
    lazy var emotionButton: UIButton = {
        let emotionBtn = UIButton(type: .custom)
        emotionBtn.setImage(#imageLiteral(resourceName: "ToolViewEmotion"), for: .normal)
        emotionBtn.setImage(#imageLiteral(resourceName: "ToolViewEmotionHL"), for: .highlighted)
        emotionBtn.addTarget(self, action: #selector(emotionBtnClick(_:)), for: .touchUpInside)
        return emotionBtn
    }()
    lazy var moreButton: UIButton = {
        let moreBtn = UIButton(type: .custom)
        moreBtn.setImage(#imageLiteral(resourceName: "TypeSelectorBtn_Black"), for: .normal)
        moreBtn.setImage(#imageLiteral(resourceName: "TypeSelectorBtnHL_Black"), for: .highlighted)
        moreBtn.addTarget(self, action: #selector(moreBtnClick(_:)), for: .touchUpInside)
        return moreBtn
    }()
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    init(_ keyboard:PropertyObservable<KeyboardType>) {
        self.init()
        self.keyboardType = keyboard
    }
    
    private func setup() {
        do {
            self.backgroundColor = kChatKeyboardBgColor
            
            addSubview(textView)
            addSubview(voiceButton)
            addSubview(recordButton)
            addSubview(emotionButton)
            addSubview(moreButton)
            addSubview(reasonLabel)
            
            
            voiceButton.snp.makeConstraints { make in
                make.left.equalTo(self).offset(margin)
                make.bottom.equalTo(self).offset(0-margin)
                make.width.height.equalTo(btnWidthOrHeight)
            }
            
            moreButton.snp.makeConstraints { make in
                make.right.equalTo(self).offset(0-margin)
                make.bottom.equalTo(self).offset(0-margin)
                make.width.height.equalTo(btnWidthOrHeight)
            }
            
            emotionButton.snp.makeConstraints { make in
                make.right.equalTo(moreButton.snp.left).offset(0-margin)
                make.bottom.equalTo(self).offset(0-margin)
                make.width.height.equalTo(btnWidthOrHeight)
            }
            
            textView.snp.makeConstraints { make in
                make.left.equalTo(voiceButton.snp.right).offset(margin)
                make.right.equalTo(emotionButton.snp.left).offset(0-margin)
                make.bottom.equalTo(self).offset(0-margin)
                //                make.height.equalTo(btnWidthOrHeight)
                make.height.greaterThanOrEqualTo(btnWidthOrHeight)
                make.height.lessThanOrEqualTo(_5LinesHeight)
            }
            
            recordButton.snp.makeConstraints { make in
                make.left.equalTo(voiceButton.snp.right).offset(margin)
                make.right.equalTo(emotionButton.snp.left).offset(0-margin)
                make.bottom.equalTo(self).offset(0-margin)
                make.height.equalTo(btnWidthOrHeight)
            }
            
            reasonLabel.snp.makeConstraints { make in
                make.edges.equalTo(self.recordButton)
            }
            
            self.snp.makeConstraints { make in
                make.top.equalTo(textView.snp.top).offset(0-margin)
            }
        } catch {
            print(error)
        }
    }
    
    deinit {
        textView.removeObserver(self, forKeyPath: "attributedText")
    }
    
    func resignInputSection() {
        textView.resignFirstResponder()
    }
    
    @objc func voiceBtnClick(_ btn: UIButton) {
        if keyboardType?.value == .voice {
            //            keyboardType?.value = .text
            textView.alpha = 1
            recordButton.isHidden = true
            textView.becomeFirstResponder()
            voiceButton.setImage(#imageLiteral(resourceName:"ToolViewInputVoice"), for: .normal)
            voiceButton.setImage(#imageLiteral(resourceName:"ToolViewInputVoiceHL"), for: .highlighted)
        } else {
            if !AudioRecordUtils.instance.isHasPermission() {
                noAudioPermission()
                return
            }
            keyboardType?.value = .voice
            textView.resignFirstResponder()
            textView.alpha = 0
            recordButton.isHidden = false
            
            voiceButton.setImage(#imageLiteral(resourceName: "ToolViewKeyboard"), for: .normal)
            voiceButton.setImage(#imageLiteral(resourceName: "ToolViewKeyboardHL"), for: .highlighted)
        }
    }
    
    @objc func moreBtnClick(_ btn: UIButton) {
        if keyboardType?.value == .more {
            textView.becomeFirstResponder()
        } else {
            keyboardType?.value = .more
        }
    }
    
    //点击表情 button
    @objc func emotionBtnClick(_ btn: UIButton) {
        
        if keyboardType?.value == .emotion {
            textView.becomeFirstResponder()
        } else {
            keyboardType?.value = .emotion
        }
    }
    
    func noAudioPermission() {
        DispatchQueue.main.async() {
            let alertController = UIAlertController(title: "无法录音",
                                                    message: "请在iPhone的\"设置-隐私-麦克风\"选项中，允许APP访问你的手机麦克风", preferredStyle: .alert)
            let okAction = UIAlertAction(title: "好", style: .default, handler: { action in
                print("ok")
            })
            alertController.addAction(okAction)
            UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true)
        }
    }
    
    @objc func voiceBtnLongTap(_ longTap: UILongPressGestureRecognizer) {
        if longTap.state == .began {    // 长按开始
            self.replaceRecordBtnUI(isRecording: true)
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: recordBtnLongTapBegan), object: longTap)
        } else if longTap.state == .changed {   // 长按平移
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: recordBtnLongTapChanged), object: longTap)
        } else if longTap.state == .ended { // 长按结束
            self.replaceRecordBtnUI(isRecording: false)
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: recordBtnLongTapEnded), object: longTap)
        }
    }
    
    @objc func unable(_ unable: Bool,reason:String) {
        self.voiceButton.isEnabled = !unable
        self.textView.isEditable = !unable
        self.moreButton.isEnabled = !unable
        self.emotionButton.isEnabled = !unable
        self.recordButton.isEnabled = !unable
        self.reasonLabel.isHidden = !unable
        self.reasonLabel.text = reason
    }
}

extension InputSectionView: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if (text == "\n") {
            let attributedText = textView.getEmotionString()
            if attributedText.trimmingCharacters(in: .whitespaces).count == 0 {
                return false
            }
            
            textView.isScrollEnabled = false
            textView.text = ""
            let msg = ChatMessage(sessionId: Int(0), from: AppStatusManager.instance.userLoginStatus.1!, fromName: AppStatusManager.instance.userLoginStatus.2!)
            msg.avatar = AppStatusManager.instance.avatar
            msg.text = attributedText
            
            delegate?.sendMessage(sndMsg: msg)
            return false
        } else if text == "" { //如果是删除
            print("触发了删除事件")
            return !deleteAtSegment(range: range,text:text)
        }else if text == "@" {
            if !enableAt {
                return true
            }
            delegate?.showRemindVC()
            return false
        }
        atModel.onTextChange(range: range, changeText: text)
        return true
    }
    
    func deleteAtSegment(range:NSRange,text:String) -> Bool{
        let start = range.location
        print("-=-=-=\(range) == \(start)")
        if let segment = atModel.findAtSegmentByEndPosition(start: start) { //如果是从空格处删除@的人的字符串
            let deleteLength = start - segment.start
            atModel.onDeleteText(start: start, length: deleteLength)
            let attribut = NSMutableAttributedString.init(attributedString: self.textView.attributedText)
            attribut.replaceCharacters(in: NSRange(location: segment.start, length: deleteLength+1), with: "") //连带@字符串后面的空格一起删掉
            self.textView.attributedText = attribut
            return true
        } else {
            atModel.onTextChange(range: range, changeText: text)
        }
        return false
    }
    
    func textWillChange(_ textView:UITextView, text:String) {
        let frame = textView.frame;
        if text == "" { //如果是删除
            if frame.height < _6LinesHeight {
                textView.isScrollEnabled = false
            }
        } else {
            if frame.height > _5LinesHeight {
                textView.isScrollEnabled = true
            }
        }
    }
    
    func textViewDidChange(_ textView: UITextView) {
        
        let frame = textView.frame;
        let size = textView.sizeThatFits(CGSize(width: frame.width, height: CGFloat.greatestFiniteMagnitude))
        
        if (frame.height != size.height) {
            if size.height > _5LinesHeight {
                textView.isScrollEnabled = true
            } else {
                textView.isScrollEnabled = false
            }
            delegate?.inputSectionChangeHeight(newHeight: size.height)
        }
    }
    
    // 切换 录音按钮的UI
    fileprivate func replaceRecordBtnUI(isRecording: Bool) {
        if isRecording {
            recordButton.setTitle(recordBtnTextStop, for: .normal)
            recordButton.setTitle(recordBtnTextTalk, for: .highlighted)
        } else {
            recordButton.setTitle(recordBtnTextTalk, for: .normal)
            recordButton.setTitle(recordBtnTextStop, for: .highlighted)
        }
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
        
        textView.scrollRangeToVisible(NSMakeRange(textView.text.count, 1))
        
        self.textViewDidChange(textView)
    }
}

extension InputSectionView {

    func deleteAtUser(range:NSRange) -> Bool {
        for name in self.nameArr {
            let atName = self.getAtNameWith(name: name)
            print("name=\(name)")
            print("atname=\(atName)")
            let atRange:Range = self.textView.text.range(of: atName)!
            let atNSRange:NSRange = self.nsRange(from: atRange)
            if (range.location >= atNSRange.location && range.location <= atNSRange.location + atNSRange.length) {
                let mStr = NSMutableString.init(string: self.textView.text)
                mStr.deleteCharacters(in: atNSRange)
                self.textView.text = mStr as String
                self.selectedRange = NSMakeRange(atNSRange.location, 0);//定位光标
                return true
            }
        }
        return false
    }

    func getAtNameWith(name:String) -> String {
        return NSString.init(string: "@\(name)") as String
    }

    /// range转换为NSRange
    func nsRange(from range: Range<String.Index>) -> NSRange {
        return NSRange(range, in: self.textView.text)
    }


}

protocol InputSectionViewDelegate: class {
    func inputSectionChangeHeight(newHeight:CGFloat)
    func inputSectionWillChangeHeight(heightOffset: CGFloat)
    func sendMessage(sndMsg:ChatMessage)
    func messageTextTooLong()
    func showAlertMessage()
    func showRemindVC()
}
